﻿#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Sockets.h"
#include "UDPSender.generated.h"

USTRUCT(BlueprintType)
struct FAnyCustomData
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Joy Color")
	FString Name;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Joy Color")
	int32 Count;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Joy Color")
	float Scale;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Joy Color")
	FLinearColor Color;

	FAnyCustomData()
	{
		Name = "Victory!";
		Count = 1;
		Scale = 1.f;
		Color = FLinearColor::Red;
	}
};

FORCEINLINE FArchive& operator<<(FArchive& Ar, FAnyCustomData& TheStruct)
{
	Ar << TheStruct.Name;
	Ar << TheStruct.Count;
	Ar << TheStruct.Scale;
	Ar << TheStruct.Color;

	return Ar;
}

UCLASS()
class MISCELLANEOUSPROJECT_API AUDPSender : public AActor
{
	GENERATED_BODY()

public:
	AUDPSender();

	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

	virtual bool OnBeforeSender(const uint8* Data, int32 Count, const FInternetAddr& Destination);
	
	bool StartUDPSender(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort, bool UDP = false);
	
	UFUNCTION(BlueprintCallable)
	bool UDPSendString(FString ToSend);

	FORCEINLINE void ScreenMsg(const FString& Msg) const
	{
		if (!ShowOnScreenDebugMessages) return;
		GEngine->AddOnScreenDebugMessage(-1, 50.f, FColor::Red, *Msg);
	}

	FORCEINLINE void ScreenMsg(const FString& Msg, const float Value) const
	{
		if (!ShowOnScreenDebugMessages) return;
		GEngine->AddOnScreenDebugMessage(-1, 50.f, FColor::Red, FString::Printf(TEXT("%s %f"), *Msg, Value));
	}

	FORCEINLINE void ScreenMsg(const FString& Msg, const FString& Msg2) const
	{
		if (!ShowOnScreenDebugMessages) return;
		GEngine->AddOnScreenDebugMessage(-1, 50.f, FColor::Red, FString::Printf(TEXT("%s %s"), *Msg, *Msg2));
	}

public:
	bool ShowOnScreenDebugMessages;
	bool IsUDP;
	TSharedPtr<FInternetAddr> RemoteAddr;
	FSocket* SenderSocket;

private:
	bool SendMessageTo(const uint8* Data, int32 Count, int32& BytesSent, const FInternetAddr& Destination);
};
